home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
PBLIB1
/
DOC
/
CODING.TXT
next >
Wrap
Text File
|
1993-12-24
|
11KB
|
235 lines
\space 20
\CENTER on
TURBO PASCAL CODING CONVENTIONS
(mine 12/24/93)
\space 20
\CENTER off
Howard Richoux
6721 Shamrock Rd.
Lincoln, NE 68506-2821
(402) 488-5867
\new
\footer1 '@date|Turbo Pascal Coding|Page @page'
General
\join 72
I have been programming for close to 25 years, on a variety
of machines in a variety of languages. Programmer support tools seem
to lag far behind the language, appearing only when the machine or language
is about obsolete. I am particularly peeved with text editors. The
needs have changed little over the years, but command names and syntaxes
require constant retraining of fingers.
I am not fanatic about coding standards, although, I find it
very difficult to study code which doesn't conform to my own conventions.
I am willing to be persuaded to adopt any or all standards IF:
\join off
1. It doesn't require a lot of extra typing.
2. A utility is provided to convert non-conforming code to
the standard. (Not just a pretty listing).
\join on
Pascal coding conventions can be divided into (at least) two groups.
General program construction practices and formatting rules. The program
construction practices include file naming, directory organization,
code library/unit use and use of global variables. Formatting rules would
cover comments, indentation, capitalization and the layout of
procedures within a file.
Many conventions are historical in nature, based on earlier
limitations of hardware or compilers. Sometimes it is easier to maintain
the standard than to recognize that it is no longer needed. A few things
to consider are:
\join off
1. TURBO Pascal has been around since the days of the 8088 and the 10 Mbyte
disk. Between the improvements in the compiler and the hardware,
compile speed has increased by at least a factor of 100.
2. The invention of the Unit is one of the great contributions to programming.
They can be compiled separately and linked intelligently, allowing code
to be placed in logical groupings with almost no penalties in compile
time or program size.
3. Borland's implementation of Objects is another major step forward, but
I have not adapted fully to the paradigm shift. I use them frequently,
but probably not completely correctly. I view them more as extensions
to the Unit concept rather than as a religious experience.
4. Code was meant to be shared. There are enough programming jobs left to be
done that we shouldn't need to hoard our resources. All of the general
work I am doing is placed in the PUBLIC DOMAIN. Feel free to borrow,
modify, plagerize and utilize it. All I would request is a footnote
in your documentation and/or the placing of some of your code into
the public domain.
\new
Program Construction - General
\join on
Some of the programming conventions are forced on us by the
limitations of the language/compiler. Variables and Procedures need to be
declared before they are referenced. Some are imposed by the operating system.
Fiel names can only be 8 chars with a 3 char extension, 'pas' means
pascal source file, etc.
In no particular order, here are some thoughts (Remember, I don't
claim I follow all of them to the letter):
\join off
1. Minimize the use of global variables. It is too easy to reference them
or modify them in another part of the code. The penalty of stack use
and hence execution time is normally minimal, and is dwarfed by
improvements in hardware. If globals are needed, hide them in Units
or objects where the scope is at least limited.
2. *CONTROVERSIAL* Minimize the use of COMMENTS in code. Contrary to
conventional wisdom, I have found that commenting the obvious is
of no help later on, and the sheer mass of characters obscures the
code structure. I have found that a large block of comments near
the beginning of a unit can document the use of variables without
obstructing code later on.
3. Instead, Name your variables wisely. Properly chosen names can make
the code read well and self-document. I tend to favor mixed capitals
for variable names with the capitals at the start of words within
the names such as "PrintFlag" and "DecodeString".
4. Indentation can drive a stranger crazy. I can't even read code that
looks like:
IF x = 3 then
begin
DO WHILE i < 22
begin
z := 4;
end;
end
else
begin
b := 1;
end;
Some people swear by it. ( I'm not sure I have the bad example right,
but the main feature is a snakey, constantly changing indentation.)
I use:
IF x = 3 then
begin
DO WHILE i < 22
begin
z := 4;
end;
end
else begin
b := 1;
end;
With a level change of 4 or 5 spaces, code on the same lexical level
stands out, making it easier to spot unmatched begin/ends and other
syntactical problems. The objection I've heard to 5 char indentation
is that you run out of room on the right side of the line. My answer
is that in most cases, if you have to indent 4 or 5 levels, the
procedure should probably have been broken down into multiple procedures
anyway.
5. I can live with most combinations of upper and lower case letters, as long
as it is reasonably consistant. I have seen good use of capitalization
of language elements, lower case variables and also the opposite. I
came from the punch-card all capitals world, went to a religiously
all lower-case shop and wound up muddled. Over-use of upper case is
hard on the eyes without contributing much information.
6. One of the most useful and hardest conventions to do well is to name
variables, functions and procedures in such a way as to have the
name imply its origin and/or use. If all of your global boolean
flag variables are named xxxxFlag then it is much easier to
read " If PrintFlag then ...". I tend to make symmetric functions
and procedures, even when I don't need the reverse operation at present,
just so it will be there later. So, if I convert integer to string
with IntegerString, I will code, or at least mentally reserve procedures
for RealString, StringInteger for later. This also allows me to see
if the syntax is obvious, or at least straight-forward.
7. The single hardest coding function is CHANGE. When libraries have
been built up and 20 or 30 programs are using them, how can you
rename a low level procedure? This is a problem with no easy
solution. Some of it can be avoided by naming well early. Some
can be avoided by hiding functions inside units and objects. Some
can be fixed by good coding tools search and replace text processors
and the like. The problem is magnified greatly with multiple sites.
\new
Program Construction - Detail
The following is a list of recommended procedures. I will try
to use them in my code. They may not be good for all people, but
they work for me.
\join off
Variables.
1. Use as few global variables as possible.
2. Reserve one and two character names for temporary type variables
A procedure should declare them locally. Global temporaries cause
no end of trouble because the contents are uncertain.
var s,s1,s2 ... : string;
i,j,k : integer; { an old FORTRAN hold-over}
b : byte;
3. Except for very specific uses, don't bother with specific length
strings. Var ext : string; for holding file extensions is a
waste of 250+ bytes of data space, but the alternatives of
creating a type ext_string = string[3]; causes pains in
parameter passing and declarations(what did I name that file
extension type? "extstring"? "type_ext"? ...) Simply declaring
variables string[3] is a real disaster when you want to change it
to string[4].
It is worth noting that use of objects tends to move a lot of data
space onto the heap which is much more plentiful.
4. Choose variable names such that the code which uses them can be
read out loud. "DO PlaceStringOnHeap(s) until ...;" Reads better
than "DO HeapString(s) until ..."
5. Conversely, use of 3 or 4 descriptive names in a single statement
can be very hard to follow, even though technically correct.
"If (IndexMaximum > NumberofDataItems) then IncreaseSizeofDataArea;"
reads like a ton of bricks. "NdxMax", "DataCnt", and other frequently
used shortcuts are no less readable, and save typing and spelling
errors. The trick is to always use the same shortcut for the same
word.
6. The world needs to agree on the meaning of a few terms, then use
them appropriately. One man's "indent" is another woman's "offset"
or "margin" or "leftmargin" or "pad" ... This winds up being critical
for providing run-time options for utility programs. One way to
solve this is to have the library provide "free" decoding for
a host of standard options. It then becomes much easier to use
the provided options rather than code your own support.
7. Write your code such that 50+% of it is re-useable. EVERY program
should contribute at least one routine to your library. Primarily
this breaks down to taking one step back when coding and separating
the exact problem you are attempting to solve from the more general
methods you are using to solve it. For example, if you need to
decode a string which looks like "xxxxx(yyy)" into the x and y pieces,
write the routine to pass the delimiter pair as arguments (or
global variables, or compile time constants), and name the routine
such that you know that the function is general. Spend an extra 10%
of time adding error checking code and then the next program will
have a "free" component.
The cost of this (there is ALWAYS a cost) is most probably run-time
efficiency. Generalized code will not be quite as tight as code
which solves exactly the one specific problem. It has been 15-20
years since the cost of hardware was more important than programming/
debugging costs. Hardware seems to improve by a factor of 2 every
year, programmers pick up maybe 10% per year from better tools and
experience. My vote is - when given a choice between ease of coding
and speed of running, take the coding and go back and optimize later.
Chances are, you won't need to.